package edu.ucsd.ccdb;

import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import edu.ucsd.ccdb.cytoSegPopup.CytosegDialog;
import edu.ucsd.ccdb.generalDataType.BytesMeasurement;
import edu.ucsd.ccdb.tagPopup.TagDialog;
import edu.ucsd.ccdb.tagPopup.othologyService.NifServiceWrapper;
import edu.ucsd.ccdb.tagPopup.summaryPane.CCDBTagSummaryPane;
import edu.ucsd.ccdb.tagPopup.summaryPane.OnthoTagSummaryPane;
import edu.ucsd.ccdb.tagPopup.util.BareBonesBrowserLauncher;
import edu.ucsd.irods.IRODSFileString;
import edu.ucsd.irods.SQLDBQuery;

public class DetailPanel extends JPanel implements ActionListener, MouseListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JFrame mainFrame;
	private IRODSFileString file;
	private Integer MPID;
	private String baseFolder;
	
	private String username;
	private List<String> clickedFile;

	public DetailPanel ( String username, IRODSFileString file, JFrame frame, Integer MPID, String baseFolder, List<String> clickedFile ) {
		
		this.username = username;
		this.mainFrame = frame;
		this.file = file;
		this.MPID = MPID;
		this.baseFolder = baseFolder;
		
		this.clickedFile = clickedFile;
		
		this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS ));
		setBorder(BorderFactory.createEmptyBorder(7,7,7,7 ));
		
		//-----------PicPane on left --------------
		ImageIcon image = null;
		String extraAction = null;
		
		// get the image
		if ( file.isFile() ) {
			byte[] bytes = null;
			try {
				bytes = SQLDBQuery.getImageByteArray(file.getAbsolutePath());
				if (bytes!= null ) {
					 image = new ImageIcon( readImage(bytes) );
				}
				else {// else here, has an image for null
					image = new ImageIcon(  getClass().getResource("/images/X.jpg") );
					
					// only have the button if it's not ppm file
					if ( !isPPM (file.getAbsolutePath( ) ) )
						extraAction = "Fix this";
				}
			}
			catch (SQLException e){
				e.printStackTrace();
			}
		}
		if (file.isDirectory() ) {
			image = new ImageIcon( getClass().getResource("/images/FolderIcon.jpg")  );			
		}
		
		JPanel imagePane = new JPanel();
		imagePane.setLayout(new BoxLayout(imagePane, BoxLayout.Y_AXIS));
		
		JLabel imageLabel = new JLabel(image);
		
		imagePane.add(imageLabel);
		// add link to fix the image if necessary
		if (extraAction != null ) {
			imagePane.add (Box.createRigidArea(new Dimension (0,5) ));
			
			JButton fixItButton = new JButton(extraAction);
			fixItButton.addMouseListener(this);
			imagePane.add(fixItButton);
			
			if (clickedFile.contains(file.getAbsolutePath()))
				fixItButton.setEnabled(false);
		}

		if (file.isFile() && isPPM (file.getAbsolutePath() ) ) {
			System.out.println ("this is ppm");
			
			// add ppm button
			imagePane.add (Box.createRigidArea(new Dimension (0,5) ));
			
			JButton viewWIBButton = new JButton("View");
			viewWIBButton.addActionListener( new openPPM() );
			
			imagePane.add(viewWIBButton);
		}
		
		imagePane.setBorder(BorderFactory.createTitledBorder("Preview"));
		
		//-----------InfoPane on right-------------
		JPanel infoPane = new JPanel();
		infoPane.setBorder(BorderFactory.createTitledBorder("Details"));
		infoPane.setLayout(new BoxLayout(infoPane, BoxLayout.Y_AXIS));
		
		String sizeInfo = (file.isDirectory() ? "N/A" : BytesMeasurement.getReadableLength(file.getLength() ) + " (" + file.getLength() + ")") ;
		JLabel nameLabel = new JLabel("Name: " + file.getName() );
		JLabel sizeLabel = new JLabel("Size: " + sizeInfo );
		
		// add this to separate panel
		JPanel labelRowPanel = new JPanel();
		labelRowPanel.setLayout( new BoxLayout(labelRowPanel, BoxLayout.X_AXIS) );
		
		List<String> CCDBTagData = CCDBTagSummaryPane.getBriefSummary(MPID, file);
		List<String> OnthoTagData = OnthoTagSummaryPane.getBriefSummary(MPID, file, username );
		String tagData = CCDBTagData.toString();
		tagData += OnthoTagData.toString();
		JLabel labelLabel = new JLabel("Tags: " + CCDBTagData.size() + " CCDB Tag, " + OnthoTagData.size() + " Ontology Tag(s)");
		labelLabel.setToolTipText(tagData);
		JButton modifyLabelButton = new JButton("View/Modify");
		modifyLabelButton.addActionListener(this);
		
		labelRowPanel.add(labelLabel);
		labelRowPanel.add (Box.createRigidArea(new Dimension (5,0) ));
		labelRowPanel.add(modifyLabelButton);
		labelRowPanel.setAlignmentX(LEFT_ALIGNMENT);
		
		JLabel launchCytocex = new JLabel("<html>Run Software: <font color=blue><u>Launch Cytoseg<u></font></html>");
		launchCytocex.setAlignmentX (LEFT_ALIGNMENT);
		launchCytocex.addMouseListener( new LaunchCytoSeg() );
		
		JLabel lastModifiedLabel;
		if (file.isFile())
			lastModifiedLabel = new JLabel ("Last modified: " + file.getLastModifiedDate().toString() );
		else 
			lastModifiedLabel = new JLabel ("Last modified: N/A");

		// the tag display in collapsible panel
		CollapsiblePanel CCDBTagDisplayCollapsible = new CollapsiblePanel("CCDB Tags");
		CCDBTagDisplayCollapsible.setAlignmentX(LEFT_ALIGNMENT);
		for (String element: CCDBTagData)
			CCDBTagDisplayCollapsible.add(new JLabel( element ));
		
		// special case with nothing
		if (CCDBTagData.size() == 0 ) {
			CCDBTagDisplayCollapsible.add(new JLabel("<html><i>There is no CCDB Tag</i></html>"));
		}
		
		
		CollapsiblePanel onthoTagDisplayCollapsible = new CollapsiblePanel("Ontology Tags");
		onthoTagDisplayCollapsible.setAlignmentX(LEFT_ALIGNMENT);
		for (String element: OnthoTagData)
			onthoTagDisplayCollapsible.add(new JLabel( element ));
		
		if (OnthoTagData.size() == 0) {
			onthoTagDisplayCollapsible.add(new JLabel("<html><i>There is no Ontology Tag</i></html>"));
		}
		
		infoPane.add(nameLabel);
		infoPane.add(sizeLabel);
		infoPane.add(lastModifiedLabel);
		infoPane.add(launchCytocex);
		infoPane.add(labelRowPanel);
		
		
		infoPane.add(CCDBTagDisplayCollapsible);
		infoPane.add(onthoTagDisplayCollapsible);
		
		//-----------add to main panel-------------
		imagePane.setAlignmentY(TOP_ALIGNMENT);
		infoPane.setAlignmentY(TOP_ALIGNMENT);
		add (imagePane);
		add (Box.createRigidArea(new Dimension(15,0) ) );
		add (infoPane);	
	}
	
	private boolean isPPM ( String path ) {
		return path.lastIndexOf("ppm") == path.length() - 3;	// check the last occurance of the 
	}
	
	private Image readImage ( byte[] bytes) {
		Image image = null;
		
		try {
			
			InputStream in = new ByteArrayInputStream(bytes);
			image = ImageIO.read(in);
		}
		catch (IOException e){
			e.printStackTrace();
		}		
		return image;
	}

	/*
	 * (non-Javadoc)
	 * Action listener for the Modify Tag button 
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		
//		new TagDialog(mainFrame);
		TagDialog dialog = null;
		try {
			
//			Detail Panel
//			String username, IRODSFileString file, JFrame frame, Integer MPID, String baseFolder, List<String> clickedFile
//			Tag Dialog
//			String username, JFrame parent, IRODSFileString file, Integer MPID, JPanel detailView, List<String> clickedFile			
			dialog = new TagDialog ( username, mainFrame, file, MPID, this, baseFolder, clickedFile );

		} catch (Exception e1) {

			e1.printStackTrace();
		}
		
        // show it
		if (dialog != null ) {
	        dialog.setSize(new Dimension(300, 150));
	        dialog.setLocationRelativeTo(mainFrame);
	        dialog.pack();	// set all components to prefered size
	        dialog.setVisible(true);
		}
	}
	
	/*
	 * This event listener is for the "Fix it" image and refresh the pane
	 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
	 */
	public void mouseClicked(MouseEvent e) {
		
		// disable the button
		JButton button = (JButton) e.getSource();
		button.setEnabled(false);
		
		// set click to true so the next time won't appear
		clickedFile.add(file.getAbsolutePath());
		
		System.out.println ("Fix it. File path: " + file.getAbsolutePath() );
		
		try {
			NifServiceWrapper.fixAndGetImage(file.getAbsolutePath());
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
	}
	
	/*
	 * This class is to launch the cytoseg 
	 */
	private class LaunchCytoSeg implements MouseListener {

		public void mouseClicked(MouseEvent e) {
			
			System.out.println ("Click launch");
			
//			new TagDialog(mainFrame);
			
			CytosegDialog cytosegDialog = new CytosegDialog ( mainFrame, file, baseFolder );
			
	        // show it
			cytosegDialog.setSize(new Dimension(300, 150));
			cytosegDialog.setLocationRelativeTo(mainFrame);
			cytosegDialog.pack();	// set all components to preferred size
			cytosegDialog.setVisible(true);			
		}

		public void mouseEntered(MouseEvent e) {			
		}

		public void mouseExited(MouseEvent e) {			
		}

		public void mousePressed(MouseEvent e) {			
		}

		public void mouseReleased(MouseEvent e) {			
		}		
	}
	
	private class openPPM implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			// open the browser for view
			String url = "http://ccdb-portal.crbs.ucsd.edu/WebImageBrowser/cgi-bin/start.pl?flatID=irods:" + file.getAbsolutePath() ;
			BareBonesBrowserLauncher.openURL( url );
		}
		
	}

}
